//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
// Copyright 2012 Microsoft Corporation. All Rights Reserved
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.   
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
//--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

using System;
using System.Windows.Forms;

namespace PreflightClientTool
{
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using Preflight.ServiceModel.Contract;

    public partial class MainForm : Form
    {
        private IEnumerable<Target> targets;
        public MainForm()
        {
            InitializeComponent();
        }

        private IEnumerable<Target> GetCheckedTargets()
        {
            return from ListViewItem selectedItem in this.endpointList.CheckedItems select (Target) selectedItem.Tag;
        }

        private Target GetSelectedTarget()
        {
            if(this.endpointList.SelectedItems.Count > 0)
            {
                return this.endpointList.SelectedItems[0].Tag as Target;
            }

            return null;
        }

        private void ClickAddEndpoint(object sender, EventArgs e)
        {
            var newTarget = EditEndpointForm.CreateNewTarget();
            if(newTarget != null)
            {
                this.AddItem(newTarget);
            }
        }

        private void ClickEditEndpoint(object sender, EventArgs e)
        {
            var selectedTarget = this.GetSelectedTarget();
            if(selectedTarget == null)
            {
                return;
            }

            if(EditEndpointForm.EditTarget(selectedTarget))
            {
                UpdateTarget(selectedTarget);
            }
        }

        private void ClickDeleteEndpoint(object sender, EventArgs e)
        {
            var selectedTarget = this.GetSelectedTarget();
            if (selectedTarget == null)
            {
                return;
            }

            PreflightFacade.DeleteTarget(selectedTarget);
            var item = this.FindItem(selectedTarget);
            this.endpointList.Items.Remove(item);
        }

        private void ClickRunPreflightChecks(object sender, EventArgs e)
        {
            foreach(var target in this.GetCheckedTargets())
            {
                PreflightFacade.RunPreflightChecks(target, t =>
                    {
                        Action action = () => UpdateTarget(t);
                        this.BeginInvoke(action);
                    });
            }
        }


        private ListViewItem FindItem(Target target)
        {
            return this.endpointList.Items.Cast<ListViewItem>().FirstOrDefault(item => item.Tag == target);
        }

        private void UpdateTarget(Target target)
        {
            var item = FindItem(target);
            item.SubItems[1].Text = target.Endpoint.Name;
            item.SubItems[2].Text = target.State.ToString();
            item.SubItems[3].Text = target.Error;
        }

        private void ClickNode(object sender, TreeNodeMouseClickEventArgs e)
        {
            this.verificationDetails.Text = string.Empty;
            var verification = e.Node.Tag as Verification;
            if(verification == null)
            {
                return;
            }

            foreach(var message in verification.Messages)
            {
                verificationDetails.Text += string.Format("[{0}] {1}\n\n", message.Type, message.Content);
            }
        }

        private void FormLoad(object sender, EventArgs e)
        {
            var endpointsPath = Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "endpoints.dat");
            LoadTargets(endpointsPath);
        }

        private void AddItem(Target target)
        {
            var listViewItem = new ListViewItem(new[] {target.Endpoint.Name, target.State.ToString()})
                {
                    Tag = target
                };
            this.endpointList.Items.Add(listViewItem);

        }

        private void ClickOpenEndpoints(object sender, EventArgs e)
        {
            using(var openFileDialog = new OpenFileDialog())
            {
                openFileDialog.RestoreDirectory = true;
                if(openFileDialog.ShowDialog(this) == DialogResult.OK)
                {
                    LoadTargets(openFileDialog.FileName);
                }
            }
        }

        private void LoadTargets(string path)
        {
            targets = PreflightFacade.GetTargets(path);
            this.endpointList.Items.Clear();
            foreach (var target in this.targets)
            {
                AddItem(target);
            }
        }

        private void SelectItem(object sender, EventArgs e)
        {
            var selectedItem = this.GetSelectedTarget();
            var validSelection = selectedItem != null;
            editEndpointButton.Visible = validSelection;
            deleteEndpointButton.Visible = validSelection;
            this.ShowCheckResults(selectedItem);
        }

        private void ShowCheckResults(Target selectedItem)
        {

            this.resultDetailsGroupBox.Visible = false;
            if(selectedItem == null || selectedItem.State == TargetState.Unknown  || selectedItem.State == TargetState.Checking)
            {
                return;
            }

            this.resultDetailsGroupBox.Visible = true;
            this.verificationTree.Nodes.Clear();
            this.verificationDetails.Text = string.Empty;

            if (selectedItem.State == TargetState.Error)
            {
                this.verificationDetails.Text = selectedItem.Error;
                return;
            }

            this.AddCategories(selectedItem.Check.Categories);
            this.SetDescription(selectedItem.Check.Description);
        }

        private void SetDescription(Description description)
        {
            if(description == null)
            {
                return;
            }

            var name = description.Name ?? "Unknown";
            var version = description.Version ?? "Unknown";
            this.appNameAndVersion.Text = string.Format("Application Name: {0} | Application Version: {1}", name, version);
        }

        private void AddCategories(IEnumerable<Category> categories)
        {
            if(categories == null)
            {
                return;
            }

            foreach(var category in categories)
            {
                var node = new TreeNode(category.Name);
                this.verificationTree.Nodes.Add(node);

                foreach(var verification in category.Verifications)
                {
                    var passed = verification.Passed ? "Passed" : "Failed";
                    var verificationNode = new TreeNode(string.Format("{0} ({1})", verification.Name, passed))
                        {
                            Tag = verification
                        };
                    node.Nodes.Add(verificationNode);
                }
            }
        }
    }
}
